package utils ;

import java.util.Calendar ;
import java.util.Date ;
import java.util.Locale ;

/**
 * 时间处理的工具类
 * @author 80002165 @date 2017年5月12日 上午9:43:48
 */
public class DateUtils {
    
    /**
     * 获取当前系统时间(原始格式)
     */
    public static Date getCurrentDate() {
        return new Date(System.currentTimeMillis()) ;
    }
    
    public static long getCurrentSeconds() {
        return System.currentTimeMillis() / 1000 ;
    }
    
    /**
     * 获取当前时间日期的字符串
     */
    public static String getCurrentDateStr(DateFormatType dateFormatType) {
        Date date = getCurrentDate() ;
        return (String) doOperation(date, dateFormatType.getValue()) ;
    }
    
    /**
     * 时间、日期格式化成字符串
     */
    public static String formatDate(Date date, DateFormatType dateFormatType) {
        return (String) doOperation(date, dateFormatType.getValue()) ;
    }
    
    public static String formatDateBySeconds(long seconds, DateFormatType dateFormatType) {
        if (seconds < 1) {
            return "" ;
        }
        return formatDateByMillisecond(seconds * 1000, dateFormatType) ;
    }
    
    public static String formatDateByMillisecond(long millisecond, DateFormatType dateFormatType) {
        if (millisecond < 1) {
            return "" ;
        }
        return (String) doOperation(new Date(millisecond), dateFormatType.getValue()) ;
    }
    
    public static String formatDefault(Date date) {
        return (String) doOperation(date, "yyyy-MM-dd HH:mm:ss") ;
    }
    
    public static String formatDefault(long seconds) {
        if (seconds < 1) {
            return "" ;
        }
        return (String) doOperation(new Date(seconds * 1000), "yyyy-MM-dd HH:mm:ss") ;
    }
    
    /**
     * 从字符串解析成时间、日期
     */
    public static Date parseDate(String dateStr, DateFormatType dateFormatType) {
        Object date = doOperation(dateStr, dateFormatType.getValue()) ;
        return (Date) date ;
    }
    
    private static Object doOperation(Object object, String formatStr) {
        if (object == null || StringUtils.is(formatStr)) {
            // throw new RuntimeException("参数不能为空");
            return null ;
        }
        FastDateFormat format = FastDateFormat.getInstance(formatStr, Locale.CHINESE) ;
        // format.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        try {
            if (object instanceof Date)
                return format.format(object) ;
            else
                return format.parse(object.toString()) ;
        } catch (Exception e) {
            // throw new RuntimeException("操作失败", e);
            return null ;
        }
        
    }
    
    public static int daysBetween(String smdate, String bdate) throws ParseException {
        FastDateFormat sdf = FastDateFormat.getInstance("yyyy-MM-dd", Locale.CHINESE) ;
        Calendar cal = Calendar.getInstance(Locale.CHINESE) ;
        cal.clear() ;
        cal.setTime(sdf.parse(smdate)) ;
        long time1 = cal.getTimeInMillis() ;
        cal.setTime(sdf.parse(bdate)) ;
        long time2 = cal.getTimeInMillis() ;
        long between_days = (time2 - time1) / (1000 * 3600 * 24) ;
        
        return Integer.parseInt(String.valueOf(between_days)) ;
    }
    
    public static Date addDays(Date date, int days) {
        return new Date(date.getTime() + days * (24 * 60 * 60 * 1000)) ;
    }
    
    public static String friendlyTime(long seconds) {
        if (seconds < 1) {
            return "" ;
        }
        return friendlyTime(new Date(seconds * 1000)) ;
    }
    
    public static String friendlyTime(Date time) {
        if (time == null)
            return "" ;
        int ct = (int) ((System.currentTimeMillis() - time.getTime()) / 1000) ;
        if (ct < 3600)
            return Math.max(ct / 60, 1) + "分钟前" ;
        if (ct >= 3600 && ct < 86400)
            return (ct / 3600) + "小时前" ;
        if (ct >= 86400 && ct < 2592000) { // 86400 * 30
            int day = ct / 86400 ;
            return (day > 1) ? day + "天前" : "昨天" ;
        }
        if (ct >= 2592000 && ct <= 7776000) // 86400 * 30
            return (ct / 2592000) + "个月前" ;
        return (ct / 31104000) + "年前" ;
        // return formatDate(time, DateFormatType.DATE_FORMAT_STR_MINUTES) ;
    }
    
    /**
     * 比较两个时间大小 d1比d2早,返回-1, d1与d2相同,返回0 d1比d2晚,返回1
     *
     * @param d1
     *        小
     * @param d2
     *        大
     * @return 是否小
     */
    public static boolean earlier(Date d1, Date d2) {
        Calendar c1 = Calendar.getInstance(Locale.CHINESE) ;
        Calendar c2 = Calendar.getInstance(Locale.CHINESE) ;
        c1.setTime(d1) ;
        c2.setTime(d2) ;
        
        return c1.compareTo(c2) < 0 ;
    }
    
    public static boolean earlier(String d1, String d2) {
        return earlier(parseDate(d1, DateFormatType.DATE_FORMAT_STR), parseDate(d2, DateFormatType.DATE_FORMAT_STR)) ;
    }
    
    /**
     * 计算两个时间差，毫秒表示
     * 
     * @author 80002165 @date 2017年5月11日 上午11:36:15
     * @param startDate
     * @param endDate
     * @return
     */
    public static long calculationTime(Date startDate, Date endDate) {
        Calendar start = Calendar.getInstance(Locale.CHINESE) ;
        Calendar end = Calendar.getInstance(Locale.CHINESE) ;
        start.setTime(startDate) ;
        end.setTime(endDate) ;
        
        long l1 = start.getTimeInMillis() ;
        long l2 = end.getTimeInMillis() ;
        return l2 - l1 ;
    }
    
    public static long getDistanceMin(Date small, Date big) {
        long sec = 0 ;
        try {
            long diff = big.getTime() - small.getTime() ;
            sec = diff / (60 * 1000) ;
        } catch (Exception e) {
            e.printStackTrace() ;
        }
        return sec ;
    }
    
    /**
     * 计算两个时间差多少分
     *
     * @param startDate
     *        开始时间
     * @param endDate
     *        结束时间
     * @return 返回时间分钟数
     */
    public static int dateMin(Date startDate, Date endDate) {
        long min = calculationTime(startDate, endDate) ;
        if (min <= 0)
            return 0 ;
        long dateMin = min / (60 * 1000) ;
        return (int) dateMin ;
    }
    
    /**
     * 计算两个时间差多少小时
     * 
     * @author 80002165 @date 2017年5月11日 上午11:36:43
     * @param startDate
     * @param endDate
     * @return
     */
    public static int dateHour(Date startDate, Date endDate) {
        long hour = calculationTime(startDate, endDate) ;
        if (hour <= 0)
            return 0 ;
        long dateHour = hour / (60 * 60 * 1000) ;
        return (int) dateHour ;
    }
    
    /**
     * 计算两个时间差多少小时
     * 
     * @author 80002165 @date 2017年5月11日 上午11:36:57
     * @param startDate
     * @param endDate
     * @return
     */
    public static int dateDay(Date startDate, Date endDate) {
        long day = calculationTime(startDate, endDate) ;
        if (day <= 0)
            return 0 ;
        long dateDay = day / (24 * 60 * 60 * 1000) ;
        return (int) dateDay ;
    }
    
    public static String getDiffer(Date start, Date end) {
        long differ = calculationTime(start, end) ;
        if (differ <= 0)
            return "end" ;
        
        int day = (int) (differ / (24 * 60 * 60 * 1000)) ;
        
        int hour = (int) (differ / (60 * 60 * 1000)) ;
        hour = hour - day * 24 ;
        
        int min = (int) (differ / (60 * 60 * 1000)) ;
        min = min - day * 24 * 60 - hour * 60 ;
        int sec = (int) (differ / (60 * 1000)) ;
        sec = sec - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60 ;
        StringBuilder res = new StringBuilder() ;
        if (day > 0)
            res.append(day).append("天") ;
        if (hour > 0)
            res.append(hour).append("时") ;
        if (min > 0)
            res.append(min).append("分") ;
        if (sec > 0)
            res.append(sec).append("秒") ;
        return res.toString() ;
    }
    
    /**
     * 获取月份第一天
     * @author kingdee @date 2017年8月15日 下午4:29:16
     * @return
     */
    public static String getMonthFirstDay() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;
        Calendar calendar = Calendar.getInstance() ;
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH)) ;
        
        return sdf.format(calendar.getTime()) ;
    }
    
    /**
     * 获取月份最后一天
     * @author kingdee @date 2017年8月15日 下午4:30:39
     * @return
     */
    public static String getMonthLastDay() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;
        Calendar calendar = Calendar.getInstance() ;
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)) ;
        return sdf.format(calendar.getTime()) ;
    }
    
    
    /**
     * 日期格式化枚举
     * 
     * @author 80002165 @date 2017年5月11日 上午11:37:30
     */
    public enum DateFormatType {
        
        /**
         * 格式为：yyyy-MM-dd HH:mm:ss
         */
        DATE_FORMAT_STR("yyyy-MM-dd HH:mm:ss"),
        
        DATE_FORMAT_STR_MINUTES("yyyy-MM-dd HH:mm"),
        
        DATE_FORMAT_STR_WM("yyyy-MM-dd E HH:mm"),
        
        /**
         * 格式化为年月日时分秒的中文
         */
        DATE_FORMAT_STR_CHINA("yyyy年MM月dd日 HH时mm分ss秒"),
        
        /**
         * yyyy年MM月dd日 HH时mm分
         */
        DATE_FORMAT_STR_CHINA_MINUTES("yyyy年MM月dd日 HH时mm分"),
        
        DATE_FORMAT_STR_CHINA_MINUTES_TWO("yyyy年MM月dd日 HH:mm"),
        
        /**
         * 格式化为年月日到几点的中文
         */
        DATE_FORMAT_STR_CHINA_HOUR("yyyy年MM月dd日 HH点"),
        
        /**
         * 格式为：yyyyMMddHHmmss
         */
        SIMPLE_DATE_TIME_FORMAT_STR("yyyyMMddHHmmss"),
        
        /**
         * 格式为：yyyy-MM-dd
         */
        SIMPLE_DATE_FORMAT_STR("yyyy-MM-dd"),
        
        /**
         * 格式化为:yy-MM-dd
         */
        SIMPLE_DATE_FORMAT_STR_YY("yy年MM月dd日"),
        
        /**
         * 格式为：yyyy/MM/dd
         */
        SIMPLE_DATE_FORMAT_VIRGULE_STR("yyyy/MM/dd"),
        
        /**
         * 格式为：HH:mm:ss
         */
        HOUR_MINUTE_SECOND("HH:mm:ss"),
        
        /**
         * 格式为：HH:mm
         */
        HOUR_MINUTE("HH:mm") ;
        private final String value ;
        
        DateFormatType(String formatStr) {
            this.value = formatStr ;
        }
        
        public String getValue() {
            return value ;
        }
    }
    
    public static void main(String[] args) {
        Date start = parseDate("2015-05-11 12:30:00", DateFormatType.DATE_FORMAT_STR) ;
        Date end = parseDate("2015-05-14 13:30:00", DateFormatType.DATE_FORMAT_STR) ;
        System.out.println(dateMin(start, end)) ;
        System.out.println(dateHour(start, end)) ;
        System.out.println(dateDay(start, end)) ;
        System.out.println(getDiffer(start, end)) ;
    }
    
}
